#include <stdio.h>  
#include <signal.h>

#include <zsystem/core/networking/connection.h>
#include <zsystem/core/common/logdump.h>

#define BIND_ADDRESS "0.0.0.0:12345"
#define THREAD_NUMBER 4
#define BACKLOG 100

Z_BOOL g_exit=Z_FALSE;
void
sigint(int s) {
  g_exit = true;
}


class echoTcpServer : public zsystem::tcpServer {
public:
  echoTcpServer(const char* bindAddress, const Z_I32 sendBufferSize, const Z_I32 recieveBufferSize, const Z_I32 keepAliveInterval, const Z_U16 threads, const Z_I32 backlog)
  :zsystem::tcpServer(echoMessage, bindAddress, sendBufferSize, recieveBufferSize, keepAliveInterval, threads, backlog){
  }
  static void echoMessage(zsystem::listenerContainer*, zsystem::tcpConnection* connection, const Z_U16 seqId, const Z_U16 msgId, char* const buffer, const Z_U16 len)
  {
    Z_DUMP_LOG("received message( seqId = " << seqId << ")");
    if ( !connection->response(seqId, msgId, buffer, len) )
    {
      LOG(WARNING) << "send echo message failed";
    }
  }
protected:
  void onConnected(zsystem::tcpConnection* connection)
  {
    Z_DUMP_LOG("Server connection connected!");
  }
  void onDisconnected(zsystem::tcpConnection* connection)
  {
    Z_DUMP_LOG("Server connection disconnected!");
  }
};

int
main(int argc, char ** argv)
{
  google::InitGoogleLogging(argv[0]);

#ifdef WIN32
  google::SetLogDestination(INFO, "..\\..\\..\\logs\\echoserver_INFO_");
  google::SetLogDestination(WARNING, "..\\..\\..\\logs\\echoserver_WARNING_");
  google::SetLogDestination(ERROR, "..\\..\\..\\logs\\echoserver_ERROR_");

  WSADATA wsaData;  
  DWORD Ret;  
  if ((Ret = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)  {  
    printf("WSAStartup failed with error %d\n", Ret);  
    return -1;  
  }
  CHECK_EQ(evthread_use_windows_threads(), 0);
#else
  google::SetLogDestination(INFO, "/tmp/httpserver_INFO_");
  google::SetLogDestination(WARNING, "/tmp/httpserver_WARNING_");
  google::SetLogDestination(ERROR, "/tmp/httpserver_ERROR_");

//#define BIND_ADDRESS "unix:/tmp/httpServer_unittest.sock"
  CHECK_EQ(evthread_use_pthreads(), 0);
#endif

  echoTcpServer* server = Z_NEW(echoTcpServer)(BIND_ADDRESS, 1024, 1024, 60, THREAD_NUMBER, BACKLOG);
  server->start();
  
  signal(SIGINT, sigint);
  while(!g_exit)
  {
    zsystem::ssleep(5);
    Z_DUMP("connections: " << server->connections());
    google::FlushLogFiles(INFO);
  };
  Z_DUMP("to stop server");
  server->stop();
  Z_DUMP("after stop server");

  Z_DUMP("to delete server");
  Z_SAFE_DELETE(server, ~echoTcpServer);
  Z_DUMP("after delete server");
#ifdef WIN32
  WSACleanup();  
#endif
  return 0;  
}  

